/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package server;

import java.net.*;
import java.io.*;
import java.util.*;

/**
 *
 * @author berthise
 */
public class Server {

    /**
     * @TODO metre tout cela dans un thread de facon a prendre la main sur le serveur en ligue de commande.
     */
    private static final int ERROR = 3;

    private static void Server() {
    }

    /*
     * ici, on collection les connections
     */
    private static HashSet<Connection> vectConnection = new HashSet();

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        System.out.println("Demarage serveur !");
        int port = Integer.parseInt(args[0]);
        Server sev = new Server(); // permet d'appeller une methode non-static (init())
        sev.init(port);
    }

    public void init(int port) {
        // TODO code application logic here
        try {

            ServerSocket socketEcoute = new ServerSocket(port); // creatin du socket d'ecoute
            while (true) {
                Socket socketTransfert = socketEcoute.accept(); // accepter la connexion d'un client
                /* creation des flux */
                InputStream in = socketTransfert.getInputStream();
                DataInputStream entree = new DataInputStream(in);
                OutputStream out = socketTransfert.getOutputStream();
                DataOutputStream sortie = new DataOutputStream(out);

                /**
                 * on prepare le message, si l'id est deja utilise, alors on revois une erreur
                 * sinon, c'est ok
                 */
                Message mess = new Message();
                mess.readMessage(entree);
                if (!idExist(mess.getMessage())) {
                    Connection connection = new Connection(this, mess.getMessage(), sortie, entree); // creation du thread du client
                    connection.start(); // demrage du thread
                    vectConnection.add(connection); // ajout dans un vecteur de connecte
                    displayInfo();
                } else {
                    mess.writeMessage(ERROR, "server", "systemPanel", "Login " + mess.getMessage() + " is already used !");
                    mess.sendMessage(sortie);
                    entree.close();
                    sortie.close();
                }
                Thread.sleep(2000);
            }

        } catch (Exception e) {
            System.out.println("error" + e.toString());
        }
    }

    /*
     * fermeture de la connection sur le serveur d'un client
     * On le recherche dans le vecteur de connection
     * puis on ... fin
     * Affichage des information sur le serveur
     */
    public void closeClientConnection(String idClient) {
        Connection connectToRemove = null;
        for (Connection connect : vectConnection) {
            if (idClient.equalsIgnoreCase(connect.getIdConnection())) {
                try {
                    System.out.println("fin du client : " + idClient);
                    connect.closeConnection();
                } catch (Exception ex) {
                }
                connectToRemove = connect;
            }
        }
        if ((connectToRemove != null) && (vectConnection.remove(connectToRemove))) {
            displayInfo();
        }
    }

    /*
     * quelque information sur le serveur
     */
    private void displayInfo() {
        for (Connection connect : vectConnection) {
            System.out.println("nom client: " + connect.getIdConnection());
        }
        System.out.println("nb client connecter : " + vectConnection.size());
        System.out.println("-------------------------------");
    }

    /*
     * revois vrai si une connection a deja l'identifiant id
     */
    private boolean idExist(String id) {
        boolean b = false;
        for (Connection connect : vectConnection) {
            if (id.equalsIgnoreCase(connect.getIdConnection())) {
                b = true;
            }
        }
        return b;
    }
}
